function queryParse(str?: string) {
  if (!str) {
    str = location.href
  }

  if (!str.includes('?')) return {}

  const qstr = str.split('?').pop()?.replace(/#.*$/, '') || ''
  if (!qstr) return {}

  const parts = qstr.split('&').filter((val) => !!val)
  const result = {} as Obj
  parts.forEach((part: string) => {
    const [key, val = ''] = part.split('=')
    const value = decodeURIComponent(val)
    result[key] = value
  })

  return result
}

function queryStringify(data: Obj) {
  return Object.keys(data)
    .reduce((qstr, key) => {
      const value = encodeURIComponent(data[key] ?? '')
      return (qstr += `${key}=${value}&`)
    }, '')
    .replace(/&$/, '')
}

function addQuery(obj: Obj, url?: string) {
  url = url || location.href
  return url + (url.includes('?') ? '&' : '?') + queryStringify(obj)
}

function getQuery(key: string, url?: string) {
  const query = queryParse(url)
  return query[key]
}

function delQuery(keys: Array<string>, url: string) {
  const queryObj = queryParse(url)
  // not any query param, no need to del
  if (!Object.keys(queryObj).length) return url

  keys.forEach((key) => {
    delete queryObj[key]
  })
  const newQstr = queryStringify(queryObj)
  const parts = url.split('?')
  if (newQstr) {
    parts[parts.length - 1] = newQstr
  } else {
    parts.pop()
  }
  return parts.join('?')
}

function delLoginParams(url: string) {
  return delQuery(['code', 'at'], url)
}

export {
  queryParse,
  queryStringify,
  addQuery,
  getQuery,
  delLoginParams,
  delQuery,
}
